package org.com.cis.cf;

import java.text.NumberFormat;

public class PPMF extends MF {
	
	void iterate()
	{
		int user, item, jtem, irate, jrate, f;
		double x_ui, x_uj, x_uij, gradient;
		for ( user = 1; user <= userNumber; ++user) {
			int trainSize = trainSet.get(user).size();
			
			for ( int i = 0; i != trainSize; ++i) {
				item = trainSet.get(user).get(i) / 10;
				irate = trainSet.get(user).get(i) % 10;
				x_ui = predict(user, item);
				
				for ( int j = 0; j != trainSize; ++j) {
					jtem = trainSet.get(user).get(j) / 10;
					jrate = trainSet.get(user).get(j) % 10;
					
					if (irate > jrate) {
						
						x_uj = predict(user, jtem);
						x_uij = x_ui - x_uj;
						gradient = irate - jrate - x_uij;
						
						for( f = 0;  f != factorNumber; ++f){
							
							double u_f = userFactor.getQuick(user, f);
							double i_f = itemFactor.getQuick(item, f);
							double j_f = itemFactor.getQuick(jtem, f);

							double delta_u = gradient * (i_f - j_f) - regularization * u_f;
							userFactor.setQuick(user, f, userFactor.getQuick(user, f) + learnRate * delta_u);

							double delta_i = gradient * u_f - regularization * i_f;
							itemFactor.setQuick(item, f, itemFactor.getQuick(item, f) + learnRate * delta_i);
							
							double delta_j = gradient * (-u_f) - regularization * j_f;
							itemFactor.setQuick(jtem, f, itemFactor.getQuick(jtem, f) + learnRate * delta_j);
						}	
					}
				}
				
			}
		}
	}
	
	public void runModel()
	{
		for ( int r = 1; r <= maxIteration; ++r) {
			iterate();
			//ArrayList<Double> trainNdcg = calcNdcg(trainSet);
			double testNdcg1 = calcNdcg(testSet, 1, true);
			double testNdcg2 = calcNdcg(testSet, 2, true);
			double testNdcg3 = calcNdcg(testSet, 3, true);
			double testNdcg4 = calcNdcg(testSet, 4, true);
			double testNdcg5 = calcNdcg(testSet, 5, true);
			double testNdcg10 = calcNdcg(testSet, 10, true);
			System.out.print("iteration: " + r);
			
			NumberFormat nFormat=NumberFormat.getNumberInstance(); 
		    nFormat.setMaximumFractionDigits(4);
		    
		    System.out.println("\t" + nFormat.format(testNdcg1) + "  " + 
		    		nFormat.format(testNdcg2) + "  " + 
		    		nFormat.format(testNdcg3) + "  " + 
		    		nFormat.format(testNdcg4) + "  " + 
		    		nFormat.format(testNdcg5) + "  " + 
		    		nFormat.format(testNdcg10));
		    
/*			for ( int i = 0; i != testNdcg.size(); ++i) {
				System.out.print(nFormat.format(testNdcg.get(i)) + "\t");
			}
			System.out.println("\n");*/
		}
	}
}
